import cv2

img = cv2.imread("../images/chepai2.png")
img_blur = cv2.GaussianBlur(img, (5,5), 0)
img_gray = cv2.cvtColor(img_blur, cv2.COLOR_BGR2GRAY)

# 1. 开运算
kernel = cv2.getStructuringElement(0, (19, 19))
img_open = cv2.morphologyEx(img_gray, cv2.MORPH_OPEN, kernel)

# 2. 将原图像的灰度图 和 开运算的结果 进行加权求和
# 分离前景色 背景色
img_add = cv2.addWeighted(img_gray, 1, img_open, -1, 0)

# 3. 二值化
_, img_binary = cv2.threshold(
    img_add,
    127,
    255,
    cv2.THRESH_BINARY + cv2.THRESH_OTSU
)

"""
在此时寻找轮廓的话，有104个
"""

# 4. 使用Canny算法，先一步减少边缘
img_canny = cv2.Canny(img_binary, 30, 70)

# 5. 闭运算
kernel1 = cv2.getStructuringElement(0, (25, 25))
img_close = cv2.morphologyEx(img_canny, cv2.MORPH_CLOSE, kernel1)

# 6. 再来一次开运算
kernel2 = cv2.getStructuringElement(0, (19, 19))
img_open_2 = cv2.morphologyEx(img_close, cv2.MORPH_OPEN, kernel1)

"""
这个时候再去寻找轮廓，有6个
其实我们还可以进一步调整参数，减少轮廓的个数
"""

# 7. 寻找轮廓
contours, _ = cv2.findContours(
    img_open_2,
    mode=cv2.RETR_LIST,     # 查找轮廓的方式
    method=cv2.CHAIN_APPROX_SIMPLE  # 轮廓近似方法
)
# 寻找到的轮廓是一个列表，其中每个元素都是一个轮廓，轮廓是由点组成的 NumPy 数组
print(f"寻找到的轮廓的个数为：{len(contours)}")
for i, c in enumerate(contours):
    print(f"第{i+1}个轮廓的边界点的个位数为{len(c)}")

# 8. 绘制轮廓
# 一般不建议在原图上直接绘制
img_draw = img.copy()
cv2.drawContours(
    img_draw,
    contours=contours,  # 要绘制的轮廓列表
    contourIdx=-1,      # 要绘制轮廓的索引，-1表示都绘制，你也可以指定0 1 2 3 4 ...
    color=(0,0,255),
    thickness=2,        # -1表填充
    lineType=cv2.LINE_AA
)

cv2.imshow("img_gray", img_gray)
cv2.imshow("img_open", img_open)
cv2.imshow("img_add", img_add)
cv2.imshow("img_binary", img_binary)
cv2.imshow("img_canny", img_canny)
cv2.imshow("img_close", img_close)
cv2.imshow("img_open_2", img_open_2)
cv2.imshow("img_draw", img_draw)
cv2.waitKey(0)

"""
若想进一步的去提取车牌，需要遍历轮廓，
1. 进行面积筛选
2. 进行长宽比筛选
3. 进行颜色筛选【蓝色、黄色、绿色--渐变色】
"""